package com.village.friend.fifter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.village.friend.constant.MsgCodeEnum;
import com.village.friend.dto.response.BaseResponse;
import com.village.friend.entity.User;
import com.village.friend.redis.RedisService;
import com.village.friend.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;

/**
 * @Package: com.*.*.interceptor
 * @ClassName: AdminInterceptor
 * @Description:拦截器
 * @author: zk
 * @date: 2021年8月12日15:29:47
 */
public class AuthInterceptor extends HandlerInterceptorAdapter {
    private static Log log = LogFactory.getLog(AuthInterceptor.class);

    @Autowired
    RedisService redisService;
    @Autowired
    private UserService userService;

    /**
     * 在请求处理之前进行调用（Controller方法调用之前）
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
        String requestURI = request.getRequestURI();
        log.info(requestURI);
        //权限路径拦截
        response.setContentType("text/html;charset=utf-8");
        ServletOutputStream resultWriter = response.getOutputStream();
        String method = request.getMethod();
        String token = request.getParameter("token");
        if (method.contains("POST")) {
            RequestWrapper requestWrapper = new RequestWrapper(request);
            String body = requestWrapper.getBody();
            token = JSONObject.parseObject(body).getString("token");
        }
        // 判断请求信息
        if (StringUtils.isEmpty(token)) {
            resultWriter.write(getErrorTokenInfo("登录失效,请重新登录!").getBytes());
            resultWriter.flush();
            resultWriter.close();
            return false;
        }
        User user = redisService.getUser(token);
        if (user == null || user.getUid() == null || user.getGender() == null) {
            resultWriter.write(getErrorTokenInfo("登录失效,请重新登录!").getBytes());
            resultWriter.flush();
            resultWriter.close();
            return false;
        }
        String tokenNew = redisService.get("uid_" + user.getUid());
        if (!token.equals(tokenNew)) {
            resultWriter.write(getErrorTokenInfo("你已在其他设备登录!").getBytes());
            resultWriter.flush();
            resultWriter.close();
            return false;
        }
        String city = URLDecoder.decode(request.getHeader("app_city"), "UTF-8");
        Double lat = Double.parseDouble(request.getHeader("app_lat"));
        Double lng = Double.parseDouble(request.getHeader("app_lng"));
        user.setToken(token);
        user.setLatitude(lat);
        user.setLongitude(lng);
        if (city != null && city.contains("市")) {
            city = city.substring(0, city.lastIndexOf("市"));
        }
        user.setCity(city);
        redisService.setUser(token, user);
        userService.updateHeart(user.getUid(), city, user.getLongitude(), user.getLatitude());
        return true;
    }


    /**
     * 请求处理之后进行调用，但是在视图被渲染之前（Controller方法调用之后）
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    }

    /**
     * 在整个请求结束之后被调用，也就是在DispatcherServlet 渲染了对应的视图之后执行（主要是用于进行资源清理工作）
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    }

    private String getErrorTokenInfo(String msg) {
        return JSON.toJSONString(new BaseResponse(MsgCodeEnum.AUTH_ERROR, msg));
    }
}
